package com.food.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Snowflake;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.food.user.config.AlipayConfig;
import com.food.user.controller.UserAddressController;
import com.food.user.dto.*;
import com.food.user.entity.*;
import com.food.user.form.CreateOrderForm;
import com.food.user.mapper.OrderMapper;
import com.food.user.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.food.user.util.DateUtils;
import com.food.user.util.JwtUtil;
import com.food.user.util.RedisUtil;
import com.food.user.util.WebUtil;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 外卖订单 服务实现类
 * </p>
 *
 * @author 帅得一
 * @since 2023年06月17日
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Autowired
    private UserAddressService userAddressService;
    @Autowired
    private StoreInfoService storeInfoService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private OrderFoodService orderFoodService;
    @Autowired
    private ReceiveTimeConfigService receiveTimeConfigService;
    private Snowflake sf= new Snowflake();
    @Autowired
    private FoodInfoService foodInfoService;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    @Transactional
    public void createOrder(CreateOrderForm form) throws Exception{

        UserAddress byId = userAddressService.getById(form.getAddressId());
        if (byId==null){
            throw new Exception("地址不存在");
        }


        //得到当前登录用户
        String accessToken = WebUtil.getRequest().getHeader("accessToken");
        String value = redisUtil.getValue(accessToken);
        Integer id = JwtUtil.getUserId(value);
        Order order = new Order();
        order.setOrderUserId(id.longValue());
        //查询店铺
        StoreInfo storeInfo = storeInfoService.getOne(new QueryWrapper<StoreInfo>().eq("store_info_name", form.getCartReturnDto().getStoreInfoName()));
       if(storeInfo==null){
           throw new Exception("该店铺不存在下单失败");
       }


        order.setOrderStoreId(storeInfo.getStoreInfoId());
        //查询地址并装配
        UserAddress address = userAddressService.getById(form.getAddressId());
        order.setOrderUserPhone(address.getReceiverPhone());
        order.setOrderReceiveName(address.getReceiverName());
        order.setOrderAddress(address.getAddressInfo());
        //下单时间
        order.setOrderOrderDate(DateUtils.parseString(LocalDateTime.now(),"yyyy-MM-dd HH:mm:ss"));
        //状态
        order.setOrderState(5);
        order.setOrderStateName("待付款");
        order.setOrderNum(sf.nextId()+"");


        //封装商品项
        List<OrderFood> orderFoods = new ArrayList<>();
        CartReturnDto cartReturnDto = form.getCartReturnDto();
        //总价
        double totalPrice=0;
        for (UserCartDto userCartDto : cartReturnDto.getUserCartDtos()) {
            OrderFood orderFood = new OrderFood();
            FoodInfo byId1 = foodInfoService.getById(userCartDto.getFoodInfoId());
            if (byId1==null){
                throw new Exception("非法操作");
            }
            if (byId1.getFoodInfoState()!=1){
                throw new Exception("食品状态不对非法操作");
            }
            orderFood.setOrderFoodFoodId(userCartDto.getFoodInfoId());
            orderFood.setOrderFoodCount(userCartDto.getCount().intValue());
            orderFood.setOrderFoodOrderNum(order.getOrderNum());
            orderFood.setOrderFoodFoodName(userCartDto.getFoodInfoFoodName());
            totalPrice+=userCartDto.getAllPrice();
            orderFood.setOrderFoodPrice(userCartDto.getAllPrice()+"");
            orderFoods.add(orderFood);
        }
        //判断起送
        if (storeInfo.getStoreInfoInitiatePrice()!=null){
            if (totalPrice<storeInfo.getStoreInfoInitiatePrice()){
                throw new Exception("不满足起送价,下单失败");
            }
        }

        //判断下单时间
        ReceiveTimeConfig config = receiveTimeConfigService.getOne(new QueryWrapper<ReceiveTimeConfig>()
                .eq("receive_time_config_store_id", storeInfo.getStoreInfoId()));
        if (config!=null){
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
            LocalTime startTime = LocalTime.parse(config.getReceiveTimeConfigStartTime(), dateTimeFormatter);
            LocalTime endTime = LocalTime.parse(config.getReceiveTimeConfigEndTime(), dateTimeFormatter);
            System.out.println(startTime);
            System.out.println(endTime);
            if (LocalTime.now().isBefore(startTime)||LocalTime.now().isAfter(endTime)){
                throw new Exception("不在下单时间内，下单失败");
            }
        }

        orderFoodService.saveBatch(orderFoods);
        order.setOrderPrice(totalPrice+"");
        save(order);
        //15分钟后检查订单支付状态
        Message<String> checkOrder= MessageBuilder.withPayload(order.getOrderNum()).build();
        rocketMQTemplate.syncSend("order_check",checkOrder,5000,10);

        //检查支付状态
        Message<String> checkPay= MessageBuilder.withPayload(order.getOrderNum()).build();
        rocketMQTemplate.syncSend("pay_check",checkPay,5000,9);

        //删除购物车
        DeleteCartDto deleteCartDto = new DeleteCartDto();
        deleteCartDto.setId(id);
        deleteCartDto.setCartReturnDto(form.getCartReturnDto());
        Message<DeleteCartDto> deleteCart= MessageBuilder.withPayload(deleteCartDto).build();
        rocketMQTemplate.syncSend("delete_cart",deleteCart);
    }

    @Override
    public List<OrderListDto> select() {
        //得到当前登录商家账号和商铺
        String accessToken = WebUtil.getRequest().getHeader("accessToken");
        String value = redisUtil.getValue(accessToken);
        Integer id = JwtUtil.getUserId(value);

        List<Order> orders = list(new QueryWrapper<Order>().eq("order_user_id", id));
        ArrayList<OrderListDto> orderListDtos = new ArrayList<>();
        for (Order order : orders) {
            OrderListDto dto = BeanUtil.toBean(order, OrderListDto.class);
            orderListDtos.add(dto);
        }
        return orderListDtos;
    }

    @Override
    public OrderDetailDto viewDetail(String orderNum) throws Exception{
        Order o = getById(orderNum);

        //得到当前登录账号
        String accessToken = WebUtil.getRequest().getHeader("accessToken");
        String value = redisUtil.getValue(accessToken);
        Integer id = JwtUtil.getUserId(value);
        //判断该订单是否属于该用户
        if (o.getOrderUserId()!=id.longValue()){
            throw new Exception("无权查看");
        }
        //装配
        OrderDetailDto orderDetailDto = BeanUtil.toBean(o, OrderDetailDto.class);
        if (orderDetailDto.getOrderEvaluate()!=null){
            if (orderDetailDto.getOrderEvaluate()==1){
                orderDetailDto.setOrderEvaluateName("已评价");
            }else if (orderDetailDto.getOrderEvaluate()==0){
                orderDetailDto.setOrderEvaluateName("未评价");
            }
        }
       if (orderDetailDto.getOrderPayType()!=null){
           if (orderDetailDto.getOrderPayType()==1){
               orderDetailDto.setOrderPayTypeName("支付宝");
           }
       }

        //装配食品清单
        List<OrderFood> foods = orderFoodService.list(new QueryWrapper<OrderFood>().eq("order_food_order_num", orderNum));
        orderDetailDto.setOrderFoods(foods);
        return orderDetailDto;
    }

    @Override
    public String pay(String num) throws AlipayApiException {
        Order orderInfo = getById(num);
        //支付
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
        //商户订单号，商户网站订单系统中唯一订单号，必填
        String out_trade_no = num;
        //付款金额，必填
        String total_amount = orderInfo.getOrderPrice().toString();
        //订单名称，必填
        String subject = "商品支付";
        //商品描述，可空
        String body ="商品支付";

        alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
                + "\"total_amount\":\""+ total_amount +"\","
                + "\"subject\":\""+ subject +"\","
                + "\"body\":\""+ body +"\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        //请求
        return alipayClient.pageExecute(alipayRequest).getBody();
    }

    @Override
    public void payback() {
        System.out.println(1);
        HttpServletRequest request = WebUtil.getRequest();
        String trade_status = request.getParameter("trade_status");
        if (trade_status!=null&&trade_status.equals("TRADE_SUCCESS")){
            //支付成功
            //修改订单状态
            String orderNum = request.getParameter("out_trade_no");
            Order orderInfo = getById(orderNum);
            ReceiveTimeConfig config = receiveTimeConfigService.getOne(new QueryWrapper<ReceiveTimeConfig>()
                    .eq("receive_time_config_store_id", orderInfo.getOrderStoreId()));
            StoreInfo storeInfo = storeInfoService.getById(orderInfo.getOrderStoreId());
            if (orderInfo!=null){
                //判断商家是否自动接单
                if (config==null||config.getReceiveTimeConfigAutoReceive()==0) {
                    //修改状态
                    orderInfo.setOrderState(0);
                    orderInfo.setOrderStateName("已付款");
                    //默认评价
                    orderInfo.setOrderEvaluate(0);
                    //默认支付方式
                    orderInfo.setOrderPayType(1);
                    updateById(orderInfo);
                }else if (config!=null&&config.getReceiveTimeConfigAutoReceive()==1){
                    //自动接单
                    //接单时间
                    orderInfo.setOrderReceiveDate(DateUtils.parseString(LocalDateTime.now(),"yyyy-MM-dd HH:mm:ss"));
                    //修改订单状态
                    orderInfo.setOrderState(1);
                    orderInfo.setOrderStateName("商家接单");
                    updateById(orderInfo);


                    //生成订单日志
                    Message<String> orderNumMessage2= MessageBuilder.withPayload(orderNum).build();
                    rocketMQTemplate.syncSend("merchant_accept_order_log",orderNumMessage2);


                    //延时任务模拟骑士接单
                    Message<String> orderNumMessage= MessageBuilder.withPayload(orderNum).build();
                    rocketMQTemplate.syncSend("rider_receive",orderNumMessage,30,4);
                }
            }
        }
    }

    @Override
    public void success(String num) throws Exception {
        Order orderInfo = getById(num);
        //得到当前登录账号和商铺
        String accessToken = WebUtil.getRequest().getHeader("accessToken");
        String value = redisUtil.getValue(accessToken);
        Integer id = JwtUtil.getUserId(value);
        if (orderInfo.getOrderUserId()!=id.longValue()){
            throw new Exception("无权修改该订单");
        }
        if (orderInfo.getOrderState()!=3){
            throw new Exception("订单状态异常");
        }
        //修改订单状态
        orderInfo.setOrderState(4);
        orderInfo.setOrderStateName("订单已完成");

        //修改评价状态
        orderInfo.setOrderEvaluate(0);
        //送达时间
        orderInfo.setOrderReachDate(DateUtils.parseString(LocalDateTime.now(),"yyyy-MM-dd HH:mm:ss"));
        updateById(orderInfo);

        //消息统计销量
        Message<String> countNumMessage= MessageBuilder.withPayload(num).build();
        rocketMQTemplate.syncSend("count_num",countNumMessage);
    }


}
